import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Specification, Prisma } from '@prisma/client';
import { PrismaService } from 'src/db/prisma.service';
import { requestPromise } from 'src/interface';

@Injectable()
export class SpecificationService {
  constructor(private prisma: PrismaService) {}

  async findOne(
    specificationWhereUniqueInput: Prisma.SpecificationWhereUniqueInput,
  ): Promise<Specification | null> {
    return this.prisma.specification.findUnique({
      where: {
        id: +specificationWhereUniqueInput.id,
      },
    });
  }

  async findAll(params: {
    pageNum?: number;
    pageSize?: number;
    cursor?: Prisma.SpecificationWhereUniqueInput;
    name?: string;
    orderBy?: Prisma.SpecificationOrderByWithRelationInput;
  }): Promise<requestPromise> {
    const { pageNum = 1, pageSize = 10, cursor, name, orderBy } = params;
    console.log(params, 'params');
    const totalUsersCount = await this.prisma.specification.count({
      where: {
        name: {
          contains: name,
        },
      },
    });
    const specifications = await this.prisma.specification.findMany({
      skip: (pageNum - 1) * pageSize,
      take: pageSize,
      cursor,
      where: {
        name: {
          contains: name,
        },
      },
      orderBy,
      include: {
        specOptions: {
          select: {
            id: true,
            name: true,
          },
        },
      },
    });
    return {
      code: 200,
      message: 'success',
      data: {
        list: specifications,
        total: totalUsersCount,
      },
    };
  }

  async create(data: {
    name: string;
    specOptionsAdd: { name: string }[];
  }): Promise<Specification> {
    console.log(data, 'data');
    const result = await this.prisma.specification.create({
      data: {
        name: data.name,
        specOptions: {
          create: data.specOptionsAdd.map((option) => ({ name: option.name })),
        },
      },
    });
    return result;
  }

  async update(params: {
    where: Prisma.SpecificationWhereUniqueInput;
    data: {
      name: string;
      specOptionsAdd?: { name: string }[];
      specOptionsUpdate?: { id: number; name: string }[]; // id: specOptionId, data: specOptionData
      specOptionsDeleteIds?: number[]; // specOptionIds
    };
  }): Promise<any> {
    const { where, data } = params;
    console.log('params', params);
    const { specOptionsAdd, specOptionsUpdate, specOptionsDeleteIds, ...rest } =
      data;
    const updatedSpecType = await this.prisma.specification.update({
      where,
      data: {
        ...rest,
        specOptions: {
          ...(specOptionsAdd && { create: specOptionsAdd }),
          ...(specOptionsUpdate && {
            update: [
              ...specOptionsUpdate.map((update) => ({
                where: { id: update.id },
                data: {
                  name: update.name,
                },
              })),
            ],
          }),
          ...(specOptionsDeleteIds && {
            deleteMany: specOptionsDeleteIds.map((id) => ({ id: id })),
          }),
        },
      },
      include: { specOptions: true },
    });

    return updatedSpecType;
  }

  async delete(
    where: Prisma.SpecificationWhereUniqueInput,
  ): Promise<Specification> {
    await this.prisma.skuSpecOption.deleteMany({
      where: {
        specTypeId: +where.id,
      },
    });
    return this.prisma.specification.delete({
      where: {
        id: +where.id,
      },
    });
  }
}
